package com.billlv.codegenerator.service.impl;

import com.billlv.codegenerator.common.utils.JwtUtils;
import com.billlv.codegenerator.domain.entity.UserTokenEntity;
import com.billlv.codegenerator.repository.UserTokenRepository;
import com.billlv.codegenerator.service.BlacklistService;
import com.billlv.codegenerator.service.TokenService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.time.Instant;
import java.util.List;

@Slf4j
@Service
public class TokenServiceImpl implements TokenService {

    private final UserTokenRepository userTokenRepository;

    private final JwtUtils jwtUtils;

    private final BlacklistService blacklistService;


    public TokenServiceImpl(UserTokenRepository userTokenRepository, JwtUtils jwtUtils, BlacklistService blacklistService) {
        this.userTokenRepository = userTokenRepository;
        this.jwtUtils = jwtUtils;
        this.blacklistService = blacklistService;
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void saveToken(Long userId, String token) {
        Instant now = Instant.now();
        String tokenId = jwtUtils.getTokenId(token);
        // 存储 Access Token
        UserTokenEntity accessTokenEntity = new UserTokenEntity();
        accessTokenEntity.setUserId(userId);
        accessTokenEntity.setTokenId(tokenId);
        accessTokenEntity.setExpiryTime(jwtUtils.getExpirationTime(token).toInstant()); // 从 Token 中解析过期时间
        accessTokenEntity.setCreatedAt(now);
        userTokenRepository.save(accessTokenEntity);
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void addBlackListFromDatabase(Long userId){
        List<UserTokenEntity> userTokenList = userTokenRepository.findByUserId(userId);
        userTokenList.forEach(
                userToken -> {
                    blacklistService.addToBlacklist(userToken.getTokenId(),userToken.getExpiryTime().toEpochMilli());
                }
        );
        userTokenRepository.deleteByUserId(userId);
    }
}
